<?php
/**
 * @package  nuo.hook
 * @author   Nam Nguyen <nam.ngvan@gmail.com>
 * @version  1.0
 * @since    Apr 17, 2013
 */
class Nuo_Hook
{
	/**
	 * Hook registry
	 * @access  protected
	 * @var     array
	 */
	private $_vars = NULL;

	/**
	 * Do not create instance of this object
	 * @todo Implement from caching
	 */
	function __construct()
	{
		$this -> _vars = $this -> loadDb();
	}

	/**
	 * load hook from datatabe
	 * @access  public
	 * @return  void
	 */
	public function loadDb()
	{
		$table = Nuo::getTable('core/hook');

		$select = $table -> select() -> where('is_enabled=1') -> order('sort_order');

		$rows = $table -> fetchAll($select);

		$vars = array();

		foreach ($rows as $row)
		{
			$vars[$row -> action][] = $row -> plugin;
		}

		return $vars;
	}

	/**
	 * Has action
	 * @access  public
	 * @param   string  $action
	 * @return  array
	 */
	public function has($action)
	{
		return isset($this -> _vars[$action]) ? $this -> _vars[$action] : false;
	}

	/**
	 * Notify an action is occur
	 * @static
	 * @param string $action
	 * @param array $hook
	 * @param
	 */
	public function trigger($action, $caller = NULL, $params = NULL)
	{
		if (!isset($this -> _vars[$action]))
		{
			return;
		}

		foreach ($this->_vars[$action] as $plugin)
		{
			try
			{
				$handler = Nuo::getPlugin($plugin);

				if ($handler && method_exists($handler, $action))
				{
					$handler -> {$action}($caller, $params);
				}
				else
				{
					Nuo_Log::instance() -> write(strstr('{plugin}::{event} is not callable', array(
						'{plugin}' => $plugin,
						'{event}' => $action
					)));
				}
			}
			catch(Exception $e)
			{
				Nuo_Log::instance() -> write($e -> getMessage(), Nuo::ERROR);
			}
		}
	}

	/**
	 * Mass callback in hook method
	 * @param   string  $name
	 * @param   string  $action
	 * @param   object  $caller
	 * @param   array  $params
	 */
	public function batch($action, $caller = NULL, $params = NULL)
	{
		$module = Nuo::getModules();

		foreach ($module as $module)
		{
			try
			{
				$plugin = Nuo::getPlugin($module . '/hook');

				if ($plugin && method_exists($plugin, $action))
				{
					$plugin -> {$action}($caller, $params);
				}
			}
			catch(Exception $e)
			{
				// prevent exception to continue next call.
			}
		}
	}

}
